package respositories

import (
	"chat/models"
	"chat/pkg/util"
	"context"
	"errors"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
)

func getUserColl() (*mongo.Collection, error) {
	return util.Mongo.GetChatCollection("User")
}

func FindUser(user *models.User) error {
	filter := user

	c, err := getUserColl()
	if err != nil {
		return err
	}

	sr := c.FindOne(context.TODO(), filter)
	if sr.Err() != nil {
		return sr.Err()
	}

	err = sr.Decode(&user)
	if err != nil {
		return err
	}

	return nil
}

func FindUserByUserName(user *models.User) error {
	var filteruser models.User
	filteruser.UserName = user.UserName
	filter := filteruser

	c, err := getUserColl()
	if err != nil {
		return err
	}

	sr := c.FindOne(context.TODO(), filter)
	if sr.Err() != nil {
		return sr.Err()
	}

	err = sr.Decode(&user)
	if err != nil {
		return err
	}

	return nil
}

func InsertUser(user *models.User) error {
	c, err := getUserColl()
	if err != nil {
		return err
	}

	ior, err := c.InsertOne(context.TODO(), user)
	if err != nil {
		return err
	}
	user.Id = ior.InsertedID.(primitive.ObjectID)
	return nil
}

func UpdateUserById(user *models.User) error {
	c, err := getUserColl()
	if err != nil {
		return err
	}
	filter := bson.D{
		{Key: "_id", Value: user.Id},
	}
	update := bson.D{
		{Key: "$set", Value: user},
	}
	_, err = c.UpdateOne(context.TODO(), filter, update)
	if err != nil {
		return err
	}
	return nil
}

func UpdateUserByUserName(user *models.User) error {
	c, err := getUserColl()
	if err != nil {
		return err
	}
	filter := bson.D{
		{Key: "userName", Value: user.UserName},
	}
	update := bson.D{
		{Key: "$set", Value: user},
	}
	_, err = c.UpdateOne(context.TODO(), filter, update)
	if err != nil {
		return err
	}
	return nil
}

func DeleteUser(user *models.User) error {
	c, err := getUserColl()
	if err != nil {
		return err
	}
	dr, err := c.DeleteOne(context.TODO(), user)
	if err != nil {
		return err
	}
	if dr.DeletedCount != 1 {
		return errors.New("delete failed")
	}
	return nil
}
